/**
 * 
 */
package t4j.concurrency;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

class LiftOffRunner implements Runnable {
	private BlockingQueue<LiftOff> rockets;

	public LiftOffRunner(BlockingQueue<LiftOff> queue) {
		rockets = queue;
	}

	public void add(LiftOff lo) {
		try {
			rockets.put(lo);// add
		} catch (InterruptedException e) {
			System.out.println("Interrupted during put()");
		}
	}

	// 这里会不停地检查队列是否有对象，直到线程中断
	public void run() {
		try {
			while (!Thread.interrupted()) {
				LiftOff rocket = rockets.take();// 获取并移除此队列的头部，在元素变得可用之前一直等待（如果有必要）。
				System.out.println("----------");

				rocket.run();// 运行LiftOff 的run
			}
		} catch (InterruptedException e) {
			System.out.println("Waking from take()");
		}

		System.out.println("Exiting LiftOffRunner");
	}
}

public class TestBlockingQueues {
	static void getkey() {
		try {
			new BufferedReader(new InputStreamReader(System.in)).readLine();
		} catch (java.io.IOException e) {
			throw new RuntimeException(e);
		}
	}

	static void getkey(String message) {
		System.out.println(message);
		getkey();
	}

	static void test(String msg, BlockingQueue<LiftOff> queue) {
		System.out.println(msg);
		
		LiftOffRunner runner = new LiftOffRunner(queue);// 创建LiftOffRunner
		
		Thread t = new Thread(runner);// 线程运行LiftOffRunner run()，不断检查队列，直到线程中断
		
		t.start();
		
		for (int i = 0; i < 5; i++)
			runner.add(new LiftOff(3));// 队列ADD

		getkey("Press 'Enter' (" + msg + ")");// 到这里暂停，等待回车后继续运行

		t.interrupt();// 中断

		System.out.println("Finished " + msg + " test");
	}

	public static void main(String[] args) {
		test("LinkedBlockingQueue", new LinkedBlockingQueue<LiftOff>());// 无界队列

		test("ArrayBlockingQueue", new ArrayBlockingQueue<LiftOff>(3));// 固定尺寸

		test("SynchronousQueue", new SynchronousQueue<LiftOff>());
	}
}
